﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;

namespace MattDotson.GlobalToolkit
{
    /// <summary>
    /// Configuration section for Global Toolkit.  Global Toolkit can be configured either using this configuration section
    /// or by setting properties programatically on <see cref="GlobalToolkitContext"/>.
    /// </summary>
    public class GlobalToolkitConfigurationSection : ConfigurationSection
    {
        /// <summary>
        /// configuration xpath
        /// </summary>
        public const string Path = "globalToolkit";

        //property name constants
        private const string ServiceLocatorProperty = "serviceLocator";
        private const string CurrencyProperty = "currency";


        /// <summary>
        /// Gets or sets the type of the service locator.
        /// </summary>
        /// <value>The type of the service locator.</value>
        [ConfigurationProperty(ServiceLocatorProperty)]
        public Type ServiceLocatorType
        {
            get { return (Type)this[ServiceLocatorProperty]; }
            set { this[ServiceLocatorProperty] = value; }
        }

        /// <summary>
        /// Gets or sets the currency options.
        /// </summary>
        /// <value>The currency.</value>
        [ConfigurationProperty(CurrencyProperty)]
        public CurrencyConfigurationElement Currency
        {
            get { return (CurrencyConfigurationElement)this[CurrencyProperty]; }
            set { this[CurrencyProperty] = value; }
        }
    }

    /// <summary>
    /// Configuration element for configuring the <see cref="Currency"/> and associated classes.
    /// </summary>
    public class CurrencyConfigurationElement : ConfigurationElement
    {
        private const string EnableImplicitConversionProperty = "enableImplicitConversion";

        /// <summary>
        /// Gets or sets a value indicating whether [enable implicit conversion].
        /// </summary>
        /// <value>
        /// 	<c>true</c> if [enable implicit conversion]; otherwise, <c>false</c>.
        /// </value>
        [ConfigurationProperty(EnableImplicitConversionProperty, DefaultValue=false)]
        public bool EnableImplicitConversion
        {
            get { return (bool)this[EnableImplicitConversionProperty]; }
            set { this[EnableImplicitConversionProperty] = value; }
        }
    }

    /// <summary>
    /// Collection of service configurations
    /// </summary>
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1010:CollectionsShouldImplementGenericInterface")]
    public class ServiceConfigurationElementCollection : ConfigurationElementCollection
    {
        /// <summary>
        /// When overridden in a derived class, creates a new <see cref="T:System.Configuration.ConfigurationElement"/>.
        /// </summary>
        /// <returns>
        /// A new <see cref="T:System.Configuration.ConfigurationElement"/>.
        /// </returns>
        protected override ConfigurationElement CreateNewElement()
        {
            return new ServiceConfigurationElement();
        }

        /// <summary>
        /// Gets the element key for a specified configuration element when overridden in a derived class.
        /// </summary>
        /// <param name="element">The <see cref="T:System.Configuration.ConfigurationElement"/> to return the key for.</param>
        /// <returns>
        /// An <see cref="T:System.Object"/> that acts as the key for the specified <see cref="T:System.Configuration.ConfigurationElement"/>.
        /// </returns>
        protected override object GetElementKey(ConfigurationElement element)
        {
            return ((ServiceConfigurationElement)element).ServiceKey;
        }
    }

    /// <summary>
    /// Configuration element for services
    /// </summary>
    public class ServiceConfigurationElement : ConfigurationElement
    {
        /// <summary>
        /// Gets or sets the service key.
        /// </summary>
        /// <value>The service key.</value>
        [ConfigurationProperty("ServiceKey", IsKey = true, IsRequired = true)]
        public Type ServiceKey { get { return (Type)this["ServiceKey"]; } set { this["ServiceType"] = value; } }

        /// <summary>
        /// Gets or sets the type of the service.
        /// </summary>
        /// <value>The type of the service.</value>
        [ConfigurationProperty("ServiceType", IsRequired = true)]
        public Type ServiceType { get { return (Type)this["ServiceType"]; } set { this["ServiceType"] = value; } }
    }
}
